package com.mojito.learn.design.patterns;

/**
 * 单例模式
 * <p>
 * 确保一个类只有一个实例，并提供该实例的全局访问点。
 *
 * @author liufq
 * @date 2020-05-21 11:16
 */
public class SingletonPattern {

    private SingletonPattern() {
    }

    /**
     * 懒汉式
     * 优点：懒加载，没用到的时候不会占用内存
     * 缺点：有线程同步问题，每次getInstance都会同步，效率很低
     */
    private static SingletonPattern singleton0;

    public static synchronized SingletonPattern getInstance0() {
        if (singleton0 == null) {
            singleton0 = new SingletonPattern();
        }
        return singleton0;
    }

    /**
     * 双重检查式
     * 优点：线程安全、延迟加载、效率更高
     * 缺点：可以被反序列化。通过反射可以创建多个实例
     */
    private static volatile SingletonPattern singleton1;

    public static SingletonPattern getInstance1() {
        if (singleton1 == null) {
            synchronized (SingletonPattern.class) {
                if (singleton1 == null) {
                    singleton1 = new SingletonPattern();
                }
            }
        }
        return singleton1;
    }

    /**
     * 饿汉式
     * 优点：免线程同步的问题
     * 缺点：类加载就完成了实例化，没有达到懒加载，如果类没用上那资源就浪费了
     */
    private static SingletonPattern singleton2 = new SingletonPattern();

    public static SingletonPattern getInstance2() {
        return singleton2;
    }

    /**
     * 静态内部类
     * 优点：线程安全、延迟加载、效率高
     * 缺点：可以被反序列化。通过反射可以创建多个实例
     */
    private static class SingletonInstance {
        private static final SingletonPattern INSTANCE = new SingletonPattern();
    }

    public static SingletonPattern getInstance3() {
        return SingletonInstance.INSTANCE;
    }

    /**
     * 枚举式
     */
    public enum Singleton5 {

        /**
         * 单例
         */
        INSTANCE;

        public void test() {
            System.out.println("实现单例了！");
        }
    }
}
